package cz.cernilovsky.android.profileapp.storage;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.json.*;

import com.google.android.gms.location.Geofence;

import android.content.Context;
import android.util.Log;
import cz.cernilovsky.android.profileapp.model.*;

public class ProfilesStorage {
	public static final String FILE_NAME = "profiles.json";
	public static final String NAME = "name";
	public static final String ACTIONS = "actions";
	public static final String ACTION = "action";
	public static final String OPERATION = "operation";
	public static final String WIFI = "wifi";
	public static final String BLUETOOTH = "bluetooth";
	public static final String SOUNDS = "sounds";
	public static final String ON = "on";
	public static final String OFF = "off";
	public static final String NOOP = "noop";
	public static final String ID = "id";
	private static final String TAG = "ProfilesStorage";
	
	public static Profile[] loadProfiles(Context context) throws IOException, JSONException {
		System.out.println("loadProfiles");
		BufferedReader is = null;
		try {
			is = new BufferedReader(new InputStreamReader(context.openFileInput(FILE_NAME)));
			StringBuffer sb = new StringBuffer();
			String line = null;
			while((line = is.readLine()) != null) {
				sb.append(line);
				//Log.d(TAG, line);
			}
			JSONArray json = new JSONArray(sb.toString());
			if(json.length() == 0)
				return null;
			Profile[] profiles = new Profile[json.length()];
			for(int i = 0; i < json.length(); i++) {
				JSONObject profileObject = json.getJSONObject(i);
				String name = profileObject.getString(NAME);
				int id = profileObject.getInt(ID);
				profiles[i] = new Profile(id, name, new WiFiAction(getOperation(profileObject.getString(WIFI))), 
						new SoundsAction(getOperation(profileObject.getString(SOUNDS))), 
						new BluetoothAction(getOperation(profileObject.getString(BLUETOOTH))));
				System.out.println(profiles[i]);
			}
			return profiles;
		} catch(FileNotFoundException e) {}
		finally {
			if(is != null) {
				is.close();
			}
		}
		return null;
	}
	
	public static void addProfile(Profile profile, Context context) throws IOException, JSONException {
		Profile[] profiles = loadProfiles(context);
		Profile[] profiles1;
		if(profiles != null) {
			//profiles1 = Arrays.copyOf(profiles, profiles.length+1);
			profiles1 = new Profile[profiles.length+1];
			for(int i = 0; i < profiles.length; i++) {
				profiles1[i] = profiles[i];
			}
			profile.setId(getHighestId(profiles)+1);
			profiles1[profiles.length] = profile;
		} else {
			profile.setId(0);
			profiles1 = new Profile[] {profile};
		}
		saveProfiles(profiles1, context);
	}
	
	private static int getHighestId(Profile[] profiles) {
		int max = 0;
		for(Profile profile : profiles) {
			max = Math.max(profile.getId(), max);
		}
		return max;
	}
	
	public static void editProfile(Profile profile, Context context) throws IOException, JSONException {
		Profile[] profiles = loadProfiles(context);
		for(int i = 0; i < profiles.length; i++) {
			if(profiles[i].getId() == profile.getId()) {
				profiles[i] = profile;
				saveProfiles(profiles, context);
				return;
			}
		}
	}
	
	public static void deleteProfile(Profile profile, Context context) throws IOException, JSONException {
		LocationsStorage.deleteDependenciesOnProfile(profile, context);
		Profile[] profiles = loadProfiles(context);
		Profile[] profiles1 = new Profile[profiles.length-1];
		for(int i = 0,j=0; i < profiles.length; i++) {
			if(profiles[i].equals(profile)) {
				continue;
			}
			profiles1[j++] = profiles[i];
		}
		saveProfiles(profiles1, context);
	}

	public static void saveProfiles(Profile[] profiles, Context context) throws JSONException, IOException {
		JSONArray array = new JSONArray();
		for(Profile profile : profiles) {
			JSONObject object = new JSONObject();
			object.put(NAME, profile.getName());
			object.put(ID, profile.getId());
			object.put(WIFI, getOperation(profile.getWifi()));
			object.put(SOUNDS, getOperation(profile.getSounds()));
			object.put(BLUETOOTH, getOperation(profile.getBluetooth()));
			array.put(object);
		}
		BufferedWriter bw = null;
		try {
			bw = new BufferedWriter(new OutputStreamWriter(context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE)));
			bw.write(array.toString());
			bw.flush();
		} finally {
			if(bw != null)
				bw.close();
		}
	}

	private static String getOperation(Action action) throws JSONException {
		Operation op = action.getOperation();
		switch(op) {
		case ON:
			return ON;
		case OFF:
			return OFF;
		case NOOP:
			return NOOP;
		}
		throw new JSONException("Unknown operation");
	}

	private static Operation getOperation(String string) throws JSONException {
		if(string.equals(ON)) {
			return Operation.ON;
		} else if(string.equals(OFF)) {
			return Operation.OFF;
		} else if(string.equals(NOOP)) {
			return Operation.NOOP;
		}
		throw new JSONException("Unknown operation");
	}
}
